//
//  SDownLoader.m
//  SDownLoader
//
//  Created by Song on 2017/7/11.
//  Copyright © 2017年 Song. All rights reserved.
//

#import "SDownLoader.h"
#import "SFileTools.h"

// 缓存路行
#define kCachePath NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject

// 临时路径
#define kTmpPath NSTemporaryDirectory()

@interface SDownLoader() <NSURLSessionDataDelegate>

{ // 成员变量：应为不需要监听Set方法和Get方法，所以写个成员变量就可以；
    long long _tmpSize;
    long long _totalSize;
}

@property (nonatomic,strong) NSURLSession *session;
@property (nonatomic,strong) NSURLSessionConfiguration *config;

@end

@implementation SDownLoader

#pragma mark - 懒加载
-(NSURLSession *)session {
    
    if (!_session) {
        _session = [NSURLSession sessionWithConfiguration:self.config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    }
    return _session;
}

- (NSURLSessionConfiguration *)config {
    
    if (!_config) {
        _config = [NSURLSessionConfiguration defaultSessionConfiguration];
    }
    return _config;
}


#pragma mark - 业务方法
- (void)downLoader:(NSURL *)url {
    
    // 1.文件的存放
    // 下载int => temp + 名称
    // MD5 + URL 防止重复资源
    // 下载完成 => cache + 名称
    NSString* fileName = url.pathComponents.lastObject;
   
    NSString* downLoadedPath = [kCachePath stringByAppendingPathComponent:fileName];
    NSString* downLoadingPath = [kTmpPath stringByAppendingPathComponent:fileName];
   
    // 1. 判断，url地址，对应的资源，是下载完毕 (下载完成的目录里面，存在这个文件)
    // 1.1 告诉外界，下载完毕，并且传递相关信息(本地的路径，文件的大小)
    //  return
    
    if ([SFileTools fileExists:downLoadedPath]) {
        // 告诉外界，已经下载完成
        NSLog(@"已经下载完了");
        return;
    }
    
    // 2.检测，临时文件是否存在
    // 2.1 不存在：从0字节开始请求资源
  
    if (![SFileTools fileExists:downLoadingPath]) {
        // 从0字节开始请求资源
        NSLog(@"不存在，开始下载");
        [self downLoadWithURL:url offset:0];
    }
    
    // 2.2 存在，：直接，以当前的存在文件大小，作为开始字节，去网络请求资源
    // HTTP: range: 开始字节-
    // 正确的大小 1000    1001
    // 本地大小 == 总大小 ==> 移动到下载完成的路径中
    // 本地大小 > 总大小 ==> 删除本地临时缓存，从0开始下载
    // 本地大小 < 总大小 ==>
    
    // 获取本地大小
    _tmpSize = [SFileTools fileSize:downLoadingPath];
    
    [self downLoadWithURL:url offset:_tmpSize];
    // 文件的总大小获取
    // 发送网络请求
    // 同步 / 异步 ：这里必须用阻塞式的同步方式
//    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
//     request.HTTPMethod = @"HEAD";
//    NSURLResponse* response = nil;
//    NSError* error = nil;
//    
//     //过期了
//    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//    // 用这个  : 发送一个同步请求
//    if (error == nil){
//        // 我们需要的事响应头
//        NSLog(@"%@",response);
//    }

}

#pragma mark - 协议方法

// 第一次接收到相应的时候调用（响应头，并没有具体的资源内容）
// 通过这个方法，里面，系统提供的回掉代码块，可以控制，是继续请求，还是取消本次请求
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {

    
    // Content-Length 请求的大小 != 资源大小
    // 总大小
    // 本地缓存大小
    
    
    // 取资源总大小
    // 1.从 Content-Length 取出来
    // 2.如果 Content - Range 有，应该从Content - Range 里面获取
    _totalSize = [response.allHeaderFields[@"Lontent-Length"] longLongValue];
    NSString* contentRangeStr = response.allHeaderFields[@"Content-Range"];
    
    if (contentRangeStr.length != 0) {
      _totalSize = [[contentRangeStr componentsSeparatedByString:@"/"].lastObject longLongValue]; // 分割字符串 根据/
    }
    
    // 比对本地大小，和 总大小
    if (_tmpSize == _totalSize) {
        // 1.移动到下载完成文件夹
        
        // 2.取消本地请求
        return;
    }
    
    // 1000
    // 10001 这个时候代表这个请求已经失效了，需要重新请求，所以要取消请求
    if (_tmpSize > _totalSize) {
        
        // 1. 删除临时缓存
        
        // 2.从0开始下载
        
        // 3. 取消请求
        
        return;
    }
    
    // 继续🉑️数据
    
    completionHandler(NSURLSessionResponseAllow);

}

// 当用户确定，继续接受数据的时候调用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    NSLog(@"在接收后续数据");
}

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"请求完成");
}

// 请求完成的时候调用(!= 请求成功／失败)


#pragma mark - 私有方法

/**
 根据开始字节，请求资源

 @param url 资源地址
 @param offset 开始字节
 */
- (void)downLoadWithURL:(NSURL *)url offset:(long long)offset {
    
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:0];
    
    // 注意：只有这里设置了Range之后，才能再请求头里看到 Content-Range 字段
    [request setValue:[NSString stringWithFormat:@"bytes=%lld-",offset] forHTTPHeaderField:@"Range"];
    
    // session 分配的task,默认情况，挂起状态
    NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
    
    [dataTask resume];
    
}

@end
